From 3001e23e8cf517de39085f33db170da37df24b17 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 10 Apr 2021 16:58:39 +0100 Subject: Thrown potions/enderpearls: cleanup --- CONTRIBUTORS | 2 +- src/Entities/Player.cpp | 19 +++----- src/Entities/Player.h | 1 - src/Entities/SplashPotionEntity.cpp | 67 ++++++++++++++-------------- src/Entities/SplashPotionEntity.h | 33 ++------------ src/Entities/ThrownEnderPearlEntity.cpp | 77 +++++++++------------------------ src/Entities/ThrownEnderPearlEntity.h | 18 ++------ 7 files changed, 67 insertions(+), 150 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f8fa2fac5..5c33c5585 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -71,7 +71,7 @@ theophriene tigerw (Tiger Wang) tonibm19 TooAngel -tympaniplayer(Nate Palmer) +tympaniplayer (Nate Palmer) UltraCoderRU Warmist WebFreak001 diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 65fed943b..233c0a8c3 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1410,9 +1410,11 @@ void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) // ask plugins to allow teleport to the new position. if (!cRoot::Get()->GetPluginManager()->CallHookEntityTeleport(*this, m_LastPosition, Vector3d(a_PosX, a_PosY, a_PosZ))) { + m_IsTeleporting = true; + + Detach(); SetPosition({a_PosX, a_PosY, a_PosZ}); FreezeInternal(GetPosition(), false); - m_IsTeleporting = true; m_ClientHandle->SendPlayerMoveLook(); } @@ -2588,15 +2590,6 @@ void cPlayer::AttachTo(cEntity * a_AttachTo) void cPlayer::Detach() -{ - Detach(false); -} - - - - - -void cPlayer::Detach(bool a_IsTeleporting) { if (m_AttachedTo == nullptr) { @@ -2604,7 +2597,7 @@ void cPlayer::Detach(bool a_IsTeleporting) return; } - // Different detach, if this is a spectator + // Different detach, if this is a spectator: if (IsGameModeSpectator()) { GetClientHandle()->SendCameraSetTo(*this); @@ -2615,8 +2608,8 @@ void cPlayer::Detach(bool a_IsTeleporting) Super::Detach(); - // If they are teleporting, no need to figure out position - if (a_IsTeleporting) + // If they are teleporting, no need to figure out position: + if (m_IsTeleporting) { return; } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 3e35e4232..df84d25e0 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -598,7 +598,6 @@ public: // cEntity overrides: virtual void AttachTo(cEntity * a_AttachTo) override; virtual void Detach(void) override; - virtual void Detach(bool a_IsTeleporting); virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); } virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); } virtual cItem GetEquippedChestplate(void) const override { return m_Inventory.GetEquippedChestplate(); } diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp index bf23b8ffb..dece6a1ea 100644 --- a/src/Entities/SplashPotionEntity.cpp +++ b/src/Entities/SplashPotionEntity.cpp @@ -17,11 +17,9 @@ cSplashPotionEntity::cSplashPotionEntity( Vector3d a_Speed, const cItem & a_Item ): - Super(pkSplashPotion, a_Creator, a_Pos, 0.25f, 0.25f), - m_Item(a_Item), - m_DestroyTimer(-1) + Super(pkSplashPotion, a_Creator, a_Pos, a_Speed, 0.25f, 0.25f), + m_Item(a_Item) { - SetSpeed(a_Speed); m_EntityEffectType = cEntityEffect::GetPotionEffectType(a_Item.m_ItemDamage); m_EntityEffect = cEntityEffect( cEntityEffect::GetPotionEffectDuration(a_Item.m_ItemDamage), @@ -34,10 +32,30 @@ cSplashPotionEntity::cSplashPotionEntity( -void cSplashPotionEntity::OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) +void cSplashPotionEntity::Splash(Vector3d a_HitPos) { - Splash(a_HitPos); - m_DestroyTimer = 2; + // Look for entities in 8.25 (width) x 4.25 (height) cuboid _centred_ on hit position: + m_World->ForEachEntityInBox({ a_HitPos.addedY(-4.25 / 2), 8.25 / 2, 4.25 }, [this, a_HitPos](cEntity & a_Entity) + { + if (!a_Entity.IsPawn()) + { + // Not an entity that can take effects + return false; + } + + double SplashDistance = (a_Entity.GetPosition() - a_HitPos).Length(); + double Reduction = -0.25 * SplashDistance + 1.0; // y = -0.25x + 1, where x is the distance from the player. Approximation for potion splash. + Reduction = std::max(Reduction, 0.0); + + static_cast(a_Entity).AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction); + return false; + }); + + m_World->BroadcastSoundParticleEffect( + EffectID::PARTICLE_SPLASH_POTION, + a_HitPos.Floor(), + m_PotionColor + ); } @@ -46,42 +64,21 @@ void cSplashPotionEntity::OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFac void cSplashPotionEntity::OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) { + Super::OnHitEntity(a_EntityHit, a_HitPos); + a_EntityHit.TakeDamage(dtRangedAttack, this, 0, 1); Splash(a_HitPos); - m_DestroyTimer = 5; + Destroy(); } -void cSplashPotionEntity::Splash(Vector3d a_HitPos) +void cSplashPotionEntity::OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) { - double XZCalculation = 8.25/2; - double YCalculation = 4.25/2; - cBoundingBox SplashDistanceBox = cBoundingBox(a_HitPos.x - XZCalculation, a_HitPos.x + XZCalculation, a_HitPos.y - YCalculation, a_HitPos.y + YCalculation, a_HitPos.z - XZCalculation, a_HitPos.z + XZCalculation); - - m_World->ForEachEntityInBox(SplashDistanceBox, [=](cEntity & a_Entity) - { - if (!a_Entity.IsPawn()) - { - // Not an entity that can take effects - return false; - } - - // y = -0.25x + 1, where x is the distance from the player. Approximation for potion splash. - double SplashDistance = (a_Entity.GetPosition() - a_HitPos).Length(); - double Reduction = -0.25 * SplashDistance + 1.0; - Reduction = std::max(Reduction, 0.0); - - static_cast(a_Entity).AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction); - return false; - } - ); + Super::OnHitSolidBlock(a_HitPos, a_HitFace); - m_World->BroadcastSoundParticleEffect( - EffectID::PARTICLE_SPLASH_POTION, - a_HitPos.Floor(), - m_PotionColor - ); + Splash(a_HitPos); + Destroy(); } diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h index 1a51de1a7..30ca8997d 100644 --- a/src/Entities/SplashPotionEntity.h +++ b/src/Entities/SplashPotionEntity.h @@ -52,43 +52,18 @@ public: // tolua_export cEntityEffect GetEntityEffect(void) const { return m_EntityEffect; } void SetEntityEffect(cEntityEffect a_EntityEffect) { m_EntityEffect = a_EntityEffect; } -protected: +private: cEntityEffect::eType m_EntityEffectType; cEntityEffect m_EntityEffect; int m_PotionColor; cItem m_Item; - - // cProjectileEntity overrides: - virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) override; - virtual void OnHitEntity (cEntity & a_EntityHit, Vector3d a_HitPos) override; - virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override - { - if (m_DestroyTimer > 0) - { - m_DestroyTimer--; - if (m_DestroyTimer == 0) - { - Destroy(); - return; - } - } - else - { - Super::Tick(a_Dt, a_Chunk); - } - } - /** Splashes the potion, fires its particle effects and sounds @param a_HitPos The position where the potion will splash */ void Splash(Vector3d a_HitPos); -private: - /** Time in ticks to wait for the hit animation to begin before destroying */ - int m_DestroyTimer; + // cProjectileEntity overrides: + virtual void OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) override; + virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) override; } ; // tolua_export - - - - diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp index e6d708917..6fe4ce5be 100644 --- a/src/Entities/ThrownEnderPearlEntity.cpp +++ b/src/Entities/ThrownEnderPearlEntity.cpp @@ -9,22 +9,8 @@ cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed): - Super(pkEnderPearl, a_Creator, a_Pos, 0.25f, 0.25f), - m_DestroyTimer(-1) + Super(pkEnderPearl, a_Creator, a_Pos, a_Speed, 0.25f, 0.25f) { - SetSpeed(a_Speed); -} - - - - - -void cThrownEnderPearlEntity::OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) -{ - // TODO: Tweak a_HitPos based on block face. - TeleportCreator(a_HitPos); - - m_DestroyTimer = 2; } @@ -33,51 +19,30 @@ void cThrownEnderPearlEntity::OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_Hi void cThrownEnderPearlEntity::OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) { - int TotalDamage = 0; - - bool isAttachedEntity = GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, [& a_EntityHit](cPlayer & a_Entity) - { - const cEntity * attachedEntity = a_Entity.GetAttached(); - if (attachedEntity == nullptr) - { - // nothing attached - return false; - } + Super::OnHitEntity(a_EntityHit, a_HitPos); - return attachedEntity->GetUniqueID() == a_EntityHit.GetUniqueID(); - } - ); - // TODO: If entity is Ender Crystal, destroy it - - - if (!isAttachedEntity) + int Damage = 0; + if (a_EntityHit.IsEnderCrystal()) { - TeleportCreator(a_HitPos); - a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1); - m_DestroyTimer = 5; + // Endercrystals are destroyed: + Damage = CeilC(a_EntityHit.GetHealth()); } + a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); + TeleportCreator(a_HitPos); + Destroy(); } -void cThrownEnderPearlEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) +void cThrownEnderPearlEntity::OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) { - if (m_DestroyTimer > 0) - { - m_DestroyTimer--; - if (m_DestroyTimer == 0) - { - Destroy(); - return; - } - } - else - { - Super::Tick(a_Dt, a_Chunk); - } + Super::OnHitSolidBlock(a_HitPos, a_HitFace); + + TeleportCreator(a_HitPos); + Destroy(); } @@ -92,12 +57,10 @@ void cThrownEnderPearlEntity::TeleportCreator(Vector3d a_HitPos) } GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, [=](cPlayer & a_Entity) - { - // Teleport the creator here, make them take 5 damage: - a_Entity.TeleportToCoords(a_HitPos.x, a_HitPos.y + 0.2, a_HitPos.z); - a_Entity.TakeDamage(dtEnderPearl, this, 5, 0); - a_Entity.Detach(true); - return true; - } - ); + { + // Teleport the creator here, make them take 5 damage: + a_Entity.TeleportToCoords(a_HitPos.x, a_HitPos.y + 0.2, a_HitPos.z); + a_Entity.TakeDamage(dtEnderPearl, this, 5, 0); + return false; + }); } diff --git a/src/Entities/ThrownEnderPearlEntity.h b/src/Entities/ThrownEnderPearlEntity.h index c61b20401..f503c5398 100644 --- a/src/Entities/ThrownEnderPearlEntity.h +++ b/src/Entities/ThrownEnderPearlEntity.h @@ -30,23 +30,13 @@ public: // tolua_export cThrownEnderPearlEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed); -protected: - - // cProjectileEntity overrides: - virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) override; - virtual void OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) override; - virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; +private: /** Teleports the creator where the ender pearl lands */ void TeleportCreator(Vector3d a_HitPos); -private: - - /** Time in ticks to wait for the hit animation to begin before destroying */ - int m_DestroyTimer; + // cProjectileEntity overrides: + virtual void OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) override; + virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) override; } ; // tolua_export - - - - -- cgit v1.2.3